package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.domain.Destination;
import cn.wolfcode.luowowo.domain.Region;
import cn.wolfcode.luowowo.query.DestinationQuery;
import cn.wolfcode.luowowo.repository.DestinationRepository;
import cn.wolfcode.luowowo.service.IDestinationService;
import cn.wolfcode.luowowo.service.IRegionService;
import cn.wolfcode.luowowo.util.DBHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
//@Transactional mongodb事务必须复制集方式
public class DestinationServiceImpl implements IDestinationService {
    

    //Spring-boot集成redis持久化数据库
    @Autowired
    private DestinationRepository repository;
    
    @Autowired
    private IRegionService regionService;

    @Autowired
    private MongoTemplate template;


    @Override
    public void save(Destination destination) {

        destination.setId(null);
        repository.save(destination);
    }

    @Override
    public void delete(String id) {

        repository.deleteById(id);
    }

    @Override
    public void update(Destination destination) {

        repository.save(destination);
    }

    @Override
    public Destination get(String id) {
        return repository.findById(id).orElse(null);
    }

    @Override
    public List<Destination> listAll() {
        return repository.findAll();
    }

    @Override
    public List<Destination> queryDestByRegionId(String rid) {

        if(!StringUtils.hasLength(rid)){
            return null;
        }
        // 通过区域if查询区域目的地对象
        Region region = regionService.get(rid);
        // 获取对象挂载的目的地集合
        List<String> ids = region.getRefIds();

        // 通过id集合查询目的地的集合
        // select * from dest where id in(1,2,3)

        return  repository.findByIdIn(ids);
    }

    // 目的地管理列表更新/添加
    @Override
    public void saveOrUpdate(Destination destination) {

        if(StringUtils.hasLength(destination.getId())){
           this.update(destination);
        }else{
            this.save(destination);
        }
    }

    // 目的地分页查询
    @Override
    public Page<Destination> query(DestinationQuery qo) {

        Query query = new Query();

        //目的地列表页面分页关键字查询
        if(StringUtils.hasLength(qo.getKeyword())){
            query.addCriteria(Criteria.where("name").regex(qo.getKeyword()));
        }

        // 目的地分页:带条件查询
        // 实现点击中国--->点击广东---->点击广州
        if(StringUtils.hasLength(qo.getParentId())){
            query.addCriteria(Criteria.where("parentId").is(qo.getParentId()));
        }else {
            query.addCriteria(Criteria.where("parentId").is(null));
        }

        /*long totalCount = template.count(query, Destination.class);

        if(totalCount==0){
            return Page.empty();
        }*/
        Pageable pageable = PageRequest.of(qo.getCurrentPage()-1,qo.getPageSize(), Sort.Direction.DESC,"_id");

        /*query.with(pageable);

        List<Destination> list = template.find(query, Destination.class);
        return new PageImpl<>(list,pageable,totalCount);
        */

        return DBHelper.query(template,Destination.class,query,pageable);
    }

    // 1.目的地页面(吐司) 中国>>黑龙江>>哈尔滨功能实现
    @Override
    public List<Destination> queryToasts(String parentId) {

        // 最终返回的是目的地list集合
        List<Destination> list = new ArrayList<>();

        // 吐司 1.循环查出目的地(先查老爸)2.或者递归查询
        // 递归
        this.createToast(list,parentId);

        //list集合反转 123 --> 321(由于我们查到的集合目的地与我们想要的不符)
        Collections.reverse(list);

        return list;
    }
    // 通过区域id查询目的地
    @Override
    public List<Destination> queryDestByRegionIdForApi(String regionId) {

        List<Destination> list = new ArrayList<>();
        // 第一层
        // 区域:国内
        if("-1".equals(regionId)){
            // 查询所有的省份(通过父名称查询中国)
            list = repository.findByParentName("中国");
        }else{
            // 非国内
            list = this.queryDestByRegionId(regionId);
        }
        // 第二层
        for(Destination dest : list){
            // 云南(通过父id去查询父下边所有的子目的地)
            //List<Destination> childrens = repository.findByParentId(dest.getId());
            //约定:查询子目的地需要查询前5个
            /*if(childrens.size()>5){
                // 截取集合中前5个数据
                childrens = childrens.subList(0,5);
            }*/

            // JPA查询方法可以添加分页,排序操作
            Pageable pageable = PageRequest.of(0,9, Sort.Direction.ASC,"_id");

            List<Destination> childrens = repository.findByParentId(dest.getId(),pageable);


            // 携带目的地数据给页面
            dest.setChildren(childrens);
        }


        return list;
    }

    // 2.用于创建toast对象(递归)
    private void createToast(List<Destination> list, String parentId) {

        // 最初parentId是没有值得,为null时,不执行
        if(!StringUtils.hasLength(parentId)){
            return;
        }

        // 中国  广东   广州
        // 1.循环查出目的地(先查老爸)
        Destination dest = this.get(parentId);
        // 首先找广州Id因为它是有值得,所以添加到list中
        list.add(dest);

        // 先找广州
        if(StringUtils.hasLength(dest.getId())){
            // 把此处的list集合又放进了,方法参数中的list集合里,然后又看有没有老爸id
            // 若有,再调用自己,获取第二个目的地,把第二个目的地放入集合中,直至老爸id为空
            createToast(list,dest.getParentId());
        }
    }

    // 搜索:通过名称查询目的地对象
    @Override
    public Destination queryName(String name) {
        return repository.findByName(name);
    }
}
